#include "Fifo.h"
#include <iostream>


Fifo :: Fifo ( const char* nombre , bool keepOpen) {

	this->nombre = nombre;
	this->keepOpen = keepOpen;

	// se crea el fifo
	mknod ( this->nombre.c_str(), S_IFIFO|0666,0 );

	// se inicializa el descriptor en -1
	this->fileDes = -1;
}

Fifo :: ~Fifo () {
}

int Fifo :: escribir (const char* dato,int datoSize ) {

	// se abre el file descriptor para escritura
	abrir(false);

	// se escriben los datos en el fifo
	int resultado = -1;

	if( ! this->esLectura )
		resultado = write ( this->fileDes,(const void *)dato,datoSize );

	//checkear que el fifo se vuelva a abrir
	if ( keepOpen && resultado <= 0)
	{
		cerrar();
		abrir(false);
	}

	return resultado;
}

int Fifo :: leer ( char* buffer,int buffSize ) {

	// se abre el file descriptor para lectura
	abrir(true);

	// se leen los datos del fifo
	int resultado = -1;

	if( this->esLectura )
		resultado = read ( this->fileDes,(void *)buffer,buffSize );

	//checkear que el fifo se vuelva a abrir
	if ( keepOpen && resultado <= 0)
	{
		cerrar();
		abrir(true);
	}

	return resultado;
}

void Fifo :: cerrar (bool needUnlink) {
	close ( this->fileDes );

	if (needUnlink)
		unlink ( this->nombre.c_str() );

	this->fileDes = -1;

//	std::cout<<"---- "<<getpid()<<": Fifo cerrado-----"<<nombre<<std::endl;
}

void Fifo :: abrir (bool esLectura)
{
	if ( this->fileDes == -1)
	{
		mknod ( this->nombre.c_str(), S_IFIFO|0666,0 );

//		std::cout<<"---- "<<getpid()<<": abrir fifo -----"<<nombre<<std::endl;

		if (esLectura)
			this->fileDes = open ( this->nombre.c_str(), O_RDONLY );
		else
			this->fileDes = open ( this->nombre.c_str(), O_WRONLY);

		this->esLectura = esLectura;
	}
}

bool Fifo :: exists (const char* nombre)
{
	int fd = open (nombre,O_RDONLY );

	close(fd);

	return (fd > 0);

}



